home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / utility3 / wincap.zip / DIALOGS.C < prev    next >
C/C++ Source or Header  |  1991-11-05  |  31KB  |  824 lines

  1. /*
  2.  * dialogs.c
  3.  *
  4.  * Contains all the dialog procedures for WinCap Windows Screen Capture
  5.  * Program, as well as a few useful miscellaneous functions.
  6.  *
  7.  * Dialog Functions:
  8.  *
  9.  * AboutDlgProc()         // About Box
  10.  * OptionsDlgProc()       // Options Dialog
  11.  * InfoBoxDlgProc()       // InfoBox, which displays as the program first
  12.  *                        // starts up
  13.  * SavingDlgProc()        // Dialog which displays "Saving to file..."
  14.  * HelpDlgProc()          // Help Dialog
  15.  *
  16.  * Other Functions:
  17.  *
  18.  * StretchIconToWindow()  // Stretches Specified icon to fill up entire window.
  19.  *                        // This function is used in the "About" Box
  20.  * cwCenter()             // Centers a window on the display
  21.  * DrawIndent()           // Draws 3-D shadows for controls in dialog boxes
  22.  *
  23.  * Development Team: Mark Bader
  24.  *                   Patrick Schreiber
  25.  *                   Garrett McAuliffe
  26.  *                   Eric Flo
  27.  *                   Tony Claflin
  28.  *
  29.  * Written by Microsoft Product Support Services, Developer Support.
  30.  * Copyright (c) 1991 Microsoft Corporation. All rights reserved.
  31.  */
  32. #include <windows.h>
  33. #include <string.h>
  34. #include <stdlib.h>
  35. #include "WINCAP.h"
  36. #include "DIALOGS.h"
  37. #include "dibapi.h"
  38.  
  39. // VERSION is used in About dialog box
  40. #define VERSION "Version 3.00"
  41.  
  42. /* Global variables which are set in main program */
  43. extern char szAppName[20];  /* Name of app */
  44. extern HWND ghInst;         /* Handle to instance */
  45. extern HWND ghWndMain;      /* Handle to main window */
  46.  
  47. /***********************************************************************
  48.  *
  49.  *"About" Dialog Box Window Procedure
  50.  *
  51.  * Notable features:  This dialog box draws the application's icon
  52.  * in the dialog box itself. The icon is actually stretched larger to
  53.  * fit in the specified area, which must be done manually.
  54.  * See WM_PAINT case.
  55.  *
  56.  ************************************************************************/
  57.  
  58.  
  59. BOOL FAR PASCAL AboutDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
  60.                              lParam)
  61. {
  62.    switch (Message)
  63.       {
  64.    case WM_INITDIALOG:
  65.       cwCenter(hWndDlg, 0);       // Center the dialog on the screen
  66.  
  67.       // Set the version number (makes it easy to change)
  68.       SendDlgItemMessage(hWndDlg, IDC_VERSION, WM_SETTEXT, 0, (LONG)(LPSTR)
  69.                          VERSION);
  70.  
  71.       // Set focus on the OK button.  Since we set focus, return FALSE
  72.       SetFocus(GetDlgItem(hWndDlg, IDOK));
  73.       return FALSE;
  74.  
  75.    case WM_CLOSE:
  76.       /* Closing the Dialog behaves the same as Cancel               */
  77.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  78.       break;
  79.  
  80.    case WM_COMMAND:
  81.       switch (wParam)
  82.          {
  83.       case IDC_HELP:
  84.       {
  85.          FARPROC lpfnDIALOGSMsgProc;
  86.  
  87.          lpfnDIALOGSMsgProc = MakeProcInstance((FARPROC)HelpDlgProc, ghInst);
  88.          DialogBox(ghInst, (LPSTR)"Help", hWndDlg, lpfnDIALOGSMsgProc);
  89.          FreeProcInstance(lpfnDIALOGSMsgProc);
  90.       }
  91.          break;
  92.  
  93.       case IDOK:
  94.       case IDCANCEL:
  95.          EndDialog(hWndDlg, FALSE);
  96.          break;
  97.          }
  98.       break;    /* End of WM_COMMAND                                 */
  99.  
  100.    case WM_PAINT:
  101.    // This procedure must process paint messages. However, Windows
  102.    // must do standard painting *first*. Otherwise, it would be
  103.    // necessary to do standard painting manually or the application's
  104.    // painting would be overwritten. To implement this, post an
  105.    // application defined message and return FALSE to allow Windows
  106.    // to paint the dialog.
  107.       PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
  108.       return FALSE;
  109.  
  110.    case WM_REPAINT:
  111.    // This is the message posted in the WM_PAINT case above. At this
  112.    // point, standard dialog box painting is complete and the
  113.    // application can perform its custom painting.
  114.    // Call function which stretches icon to fit in window.  The window
  115.    // we want to use is the control specified by IDC_ICONAREA.  The icon
  116.    // to use is "WINCAP", which is one of the app's resources.  Also,
  117.    // draw the cool 3-D effects around the IDC_ICONAREA control.
  118.       StretchIconToWindow(GetDlgItem(hWndDlg, IDC_ICONAREA), "WINCAP");
  119.       DrawIndent(hWndDlg, IDC_ICONAREA, 2); // 2 -- special flag
  120.       break;
  121.  
  122.    default:
  123.       return FALSE;
  124.       }
  125.    return TRUE;
  126. } /* End of DIALOGSMsgProc                                      */
  127.  
  128.  
  129. /************************************************************************
  130.  *
  131.  * "Options" Dialog Box Window Procedure
  132.  *
  133.  * This procedure takes care of the processing for the "Options" dialog
  134.  * box, where the user selects which portion of the screen to capture.
  135.  *
  136.  * Notable features: This dialog box is "expanding" -- meaning that
  137.  * the user sees it as a certain size, and can press the "Options>>" key
  138.  * which causes the dialog box to get larger.
  139.  *
  140.  * Also, this Dialog Box Procedure is called using DialogBoxParam.  This
  141.  * allows us to pass a parameter into the dialog box procedure -- the
  142.  * parameter that gets passed in here is a handle to a structure holding
  143.  * all the options that the user specified in this dialog box.  This
  144.  * allows passing the options back to the main program WITHOUT using
  145.  * global variables.
  146.  *
  147.  ************************************************************************/
  148.  
  149.  
  150. BOOL FAR PASCAL OptionsDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
  151.                                lParam)
  152. {
  153.    static int iWidth, iHeight;     // Original Height & Width of Dialog -- used
  154.    // when growing dialog back to original size
  155.    static BOOL bIsLarge = TRUE;    // True if Dialog is full-size
  156.    static WORD wChecked;           // Button checked under "Single Window"
  157.    static HANDLE hOptionStruct;    // Handle to OPTIONSTRUCT, used to return data
  158.  
  159.    switch (Message)
  160.       {
  161.    case WM_INITDIALOG:
  162.    {
  163.       RECT rDialog;                   // Used to calculate dialog box shrinking
  164.       int iShrinkAmount;              // amount to shrink dialog box by
  165.       LPOPTIONSTRUCT lpOptionStruct;  // Pointer to options
  166.       char buffer[30];                // used in itoa conversion
  167.       RECT rDividingLine;             // Location of Dividing Line, which is
  168.                                       // used to shrink dialog box
  169.  
  170.       // Because DialogBoxParam() was used to invoke this dialog box,
  171.       // lParam contains a handle to the OPTIONSTRUCT, which contains the
  172.       // defualt values. Place user input in this structure before returning.
  173.  
  174.       hOptionStruct = (HANDLE)LOWORD(lParam);
  175.       cwCenter(hWndDlg, 0);                   // Center dialog on screen
  176.  
  177.       /*
  178.        * Shrink the window so the options do not appear - to do this,
  179.        * just call MoveWindow() with a smaller height.
  180.        */
  181.       GetWindowRect(hWndDlg, &rDialog);        // Get window rect in screen coords
  182.       iWidth = rDialog.right - rDialog.left;  // Calculate original Width & Height
  183.       iHeight = rDialog.bottom - rDialog.top;
  184.  
  185.       // Find position of IDC_DIVIDINGLINE in dialog, and shrink up to
  186.       // this control.  The reason we do this instead of making the iShrinkAmount
  187.       // a hard-coded value is that the dialog box may be different sizes
  188.       // depending on the display driver.
  189.       GetWindowRect(GetDlgItem(hWndDlg, IDC_DIVIDINGLINE), &rDividingLine);
  190.       iShrinkAmount = rDialog.bottom - rDividingLine.bottom;
  191.  
  192.       // Shrink dialog box - last parameter is TRUE so dialog is redrawn
  193.       MoveWindow(hWndDlg, rDialog.left, rDialog.top, iWidth, iHeight -
  194.                  iShrinkAmount, TRUE);
  195.       bIsLarge = FALSE;                       // We aren't large any more
  196.  
  197.       /****************************************************************
  198.        * Use the default options contained in the OPTIONSTRUCT to check
  199.        * and enable the corresponding windows, check boxes and buttons
  200.        ****************************************************************/
  201.       lpOptionStruct = (LPOPTIONSTRUCT)GlobalLock(hOptionStruct);
  202.       if (lpOptionStruct)
  203.       {
  204.       // Send messages which set the correct options from
  205.       // the default options listed in the lpOptionStruct.
  206.          SendMessage(hWndDlg, WM_COMMAND, lpOptionStruct->iOptionWindow, 0L);
  207.          SendMessage(hWndDlg, WM_COMMAND, lpOptionStruct->iOptionArea, 0L);
  208.          wChecked = lpOptionStruct->iOptionWindow;
  209.          SendMessage(hWndDlg, WM_COMMAND, lpOptionStruct->iOptionPrint, 0L);
  210.          if (IsDlgButtonChecked(hWndDlg, IDC_SCALE))
  211.          {
  212.             SetDlgItemText(hWndDlg, IDC_XAXIS, (LPSTR)itoa(lpOptionStruct->
  213.                            iXScale, buffer, 10));
  214.             SetDlgItemText(hWndDlg, IDC_YAXIS, (LPSTR)itoa(lpOptionStruct->
  215.                            iYScale, buffer, 10));
  216.          }
  217.  
  218.          // Set the text into the filename edit control
  219.          SetDlgItemText(hWndDlg, IDC_FILETEXT, (LPSTR)lpOptionStruct->
  220.                         szFileName);
  221.  
  222.          // Check/Uncheck and disable/enable the File and Printer
  223.          // check boxes
  224.          CheckDlgButton(hWndDlg, IDC_FILE, (lpOptionStruct->iOptionDest) &
  225.                         OPTION_FILE);
  226.          EnableWindow(GetDlgItem(hWndDlg, IDC_FILETEXT), (lpOptionStruct->
  227.                       iOptionDest) & OPTION_FILE);
  228.          CheckDlgButton(hWndDlg, IDC_PRINTER, (lpOptionStruct->iOptionDest) &
  229.                         OPTION_PRINTER);
  230.          EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), (lpOptionStruct
  231.                       ->iOptionDest) & OPTION_PRINTER);
  232.          GlobalUnlock(hOptionStruct);
  233.       }
  234.    }
  235.       break; /* End of WM_INITDIALOG                                 */
  236.  
  237.    case WM_CLOSE:
  238.       /* Closing the Dialog should behave the same as Cancel          */
  239.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  240.       break;
  241.  
  242.    case WM_COMMAND:
  243.       switch (wParam)
  244.          {
  245.       // If user checks any of the buttons in a group, make sure
  246.       // that the other buttons in the group get unchecked
  247.       case IDC_SINGLEWINDOW: /* Radiobutton text: "Single Window"    */
  248.          CheckRadioButton(hWndDlg, IDC_SINGLEWINDOW, IDC_PARTIALSCREEN,
  249.                           IDC_SINGLEWINDOW);
  250.  
  251.       // Enable the options which are applicable to this case --
  252.       // the IDC_ENTIRESCREEN and the IDC_PARTIALSCREEN options
  253.       // might have these disabled...
  254.          EnableWindow(GetDlgItem(hWndDlg, IDC_ENTIREWINDOW), TRUE);
  255.          EnableWindow(GetDlgItem(hWndDlg, IDC_CLIENTAREAONLY), TRUE);
  256.          CheckRadioButton(hWndDlg, IDC_ENTIREWINDOW, IDC_CLIENTAREAONLY,
  257.                           wChecked);
  258.          break;
  259.  
  260.       case IDC_ENTIRESCREEN: /* Radiobutton text: "Entire Screen"    */
  261.       case IDC_PARTIALSCREEN: /* Radiobutton text: "Rubber Band Portion"*/
  262.          CheckRadioButton(hWndDlg, IDC_SINGLEWINDOW, IDC_PARTIALSCREEN, wParam
  263.                           );
  264.  
  265.       // Now, disable the options that are only applicable to
  266.       // the IDC_SINGLEWINDOW case
  267.          EnableWindow(GetDlgItem(hWndDlg, IDC_ENTIREWINDOW), FALSE);
  268.          EnableWindow(GetDlgItem(hWndDlg, IDC_CLIENTAREAONLY), FALSE);
  269.          CheckDlgButton(hWndDlg, IDC_ENTIREWINDOW, FALSE);
  270.          CheckDlgButton(hWndDlg, IDC_CLIENTAREAONLY, FALSE);
  271.          break;
  272.  
  273.       case IDC_ENTIREWINDOW: /* Radiobutton text: "Entire Window"    */
  274.       case IDC_CLIENTAREAONLY: /* Radiobutton text: "Client Area Only"*/
  275.          CheckRadioButton(hWndDlg, IDC_ENTIREWINDOW, IDC_CLIENTAREAONLY,
  276.                           wParam);
  277.          wChecked = wParam;
  278.          break;
  279.  
  280.       case IDC_BESTFIT:
  281.       case IDC_STRETCHTOPAGE:
  282.       case IDC_SCALE:
  283.          // Check the correct button
  284.          CheckRadioButton(hWndDlg, IDC_BESTFIT, IDC_SCALE, wParam);
  285.  
  286.          // And enable or disable the options under "Scale",
  287.          // depending on whether or not the IDC_SCALE button is checked
  288.          EnableWindow(GetDlgItem(hWndDlg, IDC_XAXIS), (BOOL)(wParam ==
  289.                       IDC_SCALE));
  290.          EnableWindow(GetDlgItem(hWndDlg, IDC_YAXIS), (BOOL)(wParam ==
  291.                       IDC_SCALE));
  292.          EnableWindow(GetDlgItem(hWndDlg, IDC_XTEXT), (BOOL)(wParam ==
  293.                       IDC_SCALE));
  294.          EnableWindow(GetDlgItem(hWndDlg, IDC_YTEXT), (BOOL)(wParam ==
  295.                       IDC_SCALE));
  296.          break;
  297.  
  298.       case IDC_FILE:      /* Check box "Save To File" */
  299.          // Determine if the File Text edit control should be enabled or not
  300.          EnableWindow(GetDlgItem(hWndDlg, IDC_FILETEXT), IsDlgButtonChecked(
  301.                       hWndDlg, IDC_FILE));
  302.          break;
  303.  
  304.       case IDC_PRINTER:   /* Check box "Send to Printer" */
  305.       // Determine if the 'Options>>' button should be enabled --
  306.       // enable it if the "Printer" checkbox is checked AND
  307.       // dialog box has not been grown
  308.          EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), (
  309.                       IsDlgButtonChecked(hWndDlg, IDC_PRINTER) && !bIsLarge));
  310.          break;
  311.  
  312.       case IDOK:  /* button "OK" */
  313.       {
  314.          LPOPTIONSTRUCT lpOptionStruct;
  315.          int iDest;
  316.          char szTmp[100];
  317.  
  318.          // Save the user's selection into the OPTIONSTRUCT
  319.  
  320.          if (!hOptionStruct)
  321.          {
  322.             EndDialog(hWndDlg, FALSE);
  323.             break;
  324.          }
  325.          lpOptionStruct = (LPOPTIONSTRUCT)GlobalLock(hOptionStruct);
  326.          if (!lpOptionStruct)
  327.          {
  328.             EndDialog(hWndDlg, FALSE);
  329.             break;
  330.          }
  331.          if (IsDlgButtonChecked(hWndDlg, IDC_SINGLEWINDOW))
  332.             lpOptionStruct->iOptionArea = IDC_SINGLEWINDOW;
  333.          if (IsDlgButtonChecked(hWndDlg, IDC_ENTIRESCREEN))
  334.             lpOptionStruct->iOptionArea = IDC_ENTIRESCREEN;
  335.          if (IsDlgButtonChecked(hWndDlg, IDC_PARTIALSCREEN))
  336.             lpOptionStruct->iOptionArea = IDC_PARTIALSCREEN;
  337.          if (IsDlgButtonChecked(hWndDlg, IDC_ENTIREWINDOW))
  338.             lpOptionStruct->iOptionWindow = IDC_ENTIREWINDOW;
  339.          if (IsDlgButtonChecked(hWndDlg, IDC_CLIENTAREAONLY))
  340.             lpOptionStruct->iOptionWindow = IDC_CLIENTAREAONLY;
  341.          if (IsDlgButtonChecked(hWndDlg, IDC_BESTFIT))
  342.             lpOptionStruct->iOptionPrint = IDC_BESTFIT;
  343.          if (IsDlgButtonChecked(hWndDlg, IDC_STRETCHTOPAGE))
  344.             lpOptionStruct->iOptionPrint = IDC_STRETCHTOPAGE;
  345.          if (IsDlgButtonChecked(hWndDlg, IDC_SCALE))
  346.             lpOptionStruct->iOptionPrint = IDC_SCALE;
  347.          GetDlgItemText(hWndDlg, IDC_FILETEXT, (LPSTR)lpOptionStruct->
  348.                         szFileName, 100);
  349.          iDest = 0;
  350.          if (IsDlgButtonChecked(hWndDlg, IDC_FILE))
  351.             iDest |= OPTION_FILE;
  352.          if (IsDlgButtonChecked(hWndDlg, IDC_PRINTER))
  353.             iDest |= OPTION_PRINTER;
  354.          lpOptionStruct->iOptionDest = iDest;
  355.          if (GetDlgItemText(hWndDlg, IDC_XAXIS, (LPSTR)szTmp, 100))
  356.             lpOptionStruct->iXScale = atoi(szTmp);
  357.          if (GetDlgItemText(hWndDlg, IDC_YAXIS, (LPSTR)szTmp, 100))
  358.             lpOptionStruct->iYScale = atoi(szTmp);
  359.          GlobalUnlock(hOptionStruct);
  360.          EndDialog(hWndDlg, TRUE);
  361.       }
  362.          break;
  363.  
  364.       case IDCANCEL:
  365.       /* Ignore data values entered into the controls        */
  366.       /* and dismiss the dialog window returning FALSE       */
  367.          EndDialog(hWndDlg, FALSE);
  368.          break;
  369.  
  370.       case IDC_HELP: /* Button text: "Help"                       */
  371.       {
  372.          FARPROC lpfnDIALOGSMsgProc;
  373.  
  374.          lpfnDIALOGSMsgProc = MakeProcInstance((FARPROC)HelpDlgProc, ghInst);
  375.          DialogBox(ghInst, (LPSTR)"Help", hWndDlg, lpfnDIALOGSMsgProc);
  376.          FreeProcInstance(lpfnDIALOGSMsgProc);
  377.       }
  378.          break;
  379.  
  380.       case IDC_OPTIONSBUTTON: /* Button text: "Options >>"        */
  381.       // Make the window bigger to expose the hidden portion
  382.       // of the dialog.
  383.          if (!bIsLarge)  // Only do it if we aren't already large
  384.          {
  385.             RECT rDialog;
  386.  
  387.             GetWindowRect(hWndDlg, &rDialog);    // Get window rect in screen coords
  388.  
  389.             // Grow the dialog box - iWidth & iHeight are the original
  390.             // height & width of the dialog.
  391.             MoveWindow(hWndDlg, rDialog.left, rDialog.top, iWidth, iHeight,
  392.                        TRUE);
  393.             bIsLarge = TRUE;
  394.          }
  395.  
  396.          // Disable button
  397.          EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), FALSE);
  398.          break;
  399.  
  400.       case IDC_FOLD: /* Button Text: "<< Fold" */
  401.          // Fold the dialog box into a smaller version
  402.          if (bIsLarge)
  403.          {
  404.             RECT rDialog;
  405.             RECT rDividingLine;
  406.             int iShrinkAmount;
  407.  
  408.             GetWindowRect(hWndDlg, &rDialog);        // Get window rect in screen coords
  409.  
  410.             // Find position of IDC_DIVIDINGLINE in dialog, and shrink up to
  411.             // this control.  The reason we do this instead of making the iShrinkAmount
  412.             // a hard-coded value is that our dialog box may be different sizes
  413.             // depending on the display driver.
  414.             GetWindowRect(GetDlgItem(hWndDlg, IDC_DIVIDINGLINE), &
  415.                           rDividingLine);
  416.             iShrinkAmount = rDialog.bottom - rDividingLine.bottom;
  417.  
  418.             // Shrink dialog box - last parameter is TRUE so dialog is redrawn
  419.             MoveWindow(hWndDlg, rDialog.left, rDialog.top, iWidth, iHeight -
  420.                        iShrinkAmount, TRUE);
  421.             bIsLarge = FALSE;                       // We aren't large any more
  422.          }
  423.  
  424.          // Enable "Options" button
  425.          EnableWindow(GetDlgItem(hWndDlg, IDC_OPTIONSBUTTON), TRUE);
  426.          break;
  427.          }
  428.       break;    /* End of WM_COMMAND                                 */
  429.  
  430.    case WM_PAINT:
  431.       PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
  432.       return FALSE;
  433.  
  434.    case WM_REPAINT:
  435.       DrawIndent(hWndDlg, IDC_BOX1, 1);   // 1 is for groupbox control
  436.       DrawIndent(hWndDlg, IDC_BOX2, 1);
  437.       DrawIndent(hWndDlg, IDC_BOX3, 1);
  438.       DrawIndent(hWndDlg, IDC_BOX4, 1);
  439.       break;
  440.  
  441.    default:
  442.       return FALSE;
  443.       }
  444.    return TRUE;
  445. } /* End of DIALOGSMsgProc                                      */
  446.  
  447.  
  448.  
  449. /***********************************************************************
  450.  *
  451.  * "Info Box" Dialog Window Procedure
  452.  *
  453.  * This procedure displays the dialog box which appears when the program
  454.  * is first loaded.  It will go away after a few seconds if the user does
  455.  * not hit escape or enter or click on the OK box first.
  456.  *
  457.  * Notable features: our application icon is stretched to fill up one of
  458.  * the controls in this dialog box.
  459.  *
  460.  ************************************************************************/
  461.  
  462.  
  463. BOOL FAR PASCAL InfoBoxDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
  464.                                lParam)
  465. {
  466.    static int nTimerID = 22;       // ID for our timer - any number will do
  467.    static int nTimerLength = 5000; // Length of timer in milliseconds
  468.  
  469.    switch (Message)
  470.       {
  471.    case WM_INITDIALOG:
  472.    {
  473.       cwCenter(hWndDlg, 0);   // Center dialog on screen
  474.  
  475.       // Set timer.  This will cause a WM_TIMER message to be sent to this
  476.       // dialog procedure in nTimerLength milliseconds.
  477.       SetTimer(hWndDlg, nTimerID, nTimerLength, NULL);
  478.    }
  479.       break; /* End of WM_INITDIALOG                                 */
  480.  
  481.    case WM_TIMER:
  482.    // We got the timer message, so the time must have expired.  Make the
  483.    // dialog go away by simulating the user pressing the OK button.
  484.       PostMessage(hWndDlg, WM_COMMAND, IDOK, 0L);
  485.       break;
  486.  
  487.    case WM_CLOSE:
  488.       /* Closing the Dialog behaves the same as Cancel               */
  489.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  490.       break; /* End of WM_CLOSE                                      */
  491.  
  492.    case WM_PAINT:
  493.       // See comments in AboutBoxProc() code above
  494.       PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
  495.       return FALSE;
  496.  
  497.    case WM_REPAINT:
  498.       // See comments in AboutBoxProc() code above
  499.       StretchIconToWindow(GetDlgItem(hWndDlg, IDC_ICONAREA), "WINCAP");
  500.       DrawIndent(hWndDlg, IDC_ICONAREA, 2); // 2 -- special flag
  501.       break;
  502.  
  503.    case WM_COMMAND:
  504.       switch (wParam)
  505.          {
  506.       case IDOK:
  507.       case IDCANCEL:
  508.          KillTimer(hWndDlg, nTimerID);    // Stop timer
  509.          EndDialog(hWndDlg, TRUE);
  510.          break;
  511.          }
  512.       break;    /* End of WM_COMMAND                                 */
  513.  
  514.    default:
  515.       return FALSE;
  516.       }
  517.    return TRUE;
  518. } /* End of DIALOGSMsgProc                                      */
  519.  
  520.  
  521. /************************************************************************
  522.  *
  523.  * "Saving file to..." Dialog Box Window Procedure
  524.  *
  525.  * This is a modeless dialog box which is called when we save the bitmap
  526.  * to a file (so the user dosen't think his machine has hung).
  527.  *
  528.  ************************************************************************/
  529.  
  530.  
  531. BOOL FAR PASCAL SavingDlgProc(HWND hDlg, WORD message, WORD wParam, LONG
  532.                               lParam)
  533. {
  534.    switch (message)
  535.       {
  536.    case WM_SETFOCUS:
  537.       MessageBeep(0);
  538.       break;
  539.  
  540.    case WM_INITDIALOG:
  541.       cwCenter(hDlg, 0);  // Center dialog on screen
  542.       SetDlgItemText(hDlg, IDC_FILETEXT, (LPSTR)lParam);
  543.       return TRUE;
  544.       break;
  545.  
  546.    case WM_DESTROY:
  547.       return TRUE;
  548.       break;
  549.  
  550.    default:
  551.       return FALSE;
  552.       }
  553. }
  554.  
  555.  
  556.  
  557. /***********************************************************************
  558.  *
  559.  * "Help" Button Dialog Window Procedure
  560.  *
  561.  * This procedure displays the dialog box which appears when the user
  562.  * presses the "Help" button in either the About box, or the Options box.
  563.  *
  564.  ************************************************************************/
  565.  
  566.  
  567. BOOL FAR PASCAL HelpDlgProc(HWND hWndDlg, WORD Message, WORD wParam, LONG
  568.                             lParam)
  569. {
  570.    static HFONT hDlgFont1, hDlgFont2;
  571.    static LOGFONT lFont;
  572.  
  573.    switch (Message)
  574.       {
  575.    case WM_INITDIALOG:
  576.       cwCenter(hWndDlg, 0);   // Center dialog on screen
  577.  
  578.    // Set font of IDC_TITLE1 to a big Helv.  This procedure is explained
  579.    // in Microsoft KnowledgeBase article "Changing the Font Used by
  580.    // Dialog Controls in Windows"
  581.       lFont.lfHeight = 30;
  582.       lFont.lfWidth = 0;
  583.       lFont.lfEscapement = 0;
  584.       lFont.lfOrientation = 0;
  585.       lFont.lfWeight = 700; // bold font weight
  586.       lFont.lfItalic = 0;
  587.       lFont.lfUnderline = 0;
  588.       lFont.lfStrikeOut = 0;
  589.       lFont.lfCharSet = ANSI_CHARSET;
  590.       lFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
  591.       lFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  592.       lFont.lfQuality = PROOF_QUALITY;
  593.       lstrcpy((LPSTR)lFont.lfFaceName, (LPSTR)"");
  594.       lFont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
  595.       hDlgFont1 = CreateFontIndirect(&lFont);
  596.  
  597.       // Send WM_SETFONT message to desired control
  598.       SendDlgItemMessage(hWndDlg, IDC_TITLE1, WM_SETFONT, hDlgFont1, (DWORD)
  599.                          TRUE);
  600.       lFont.lfItalic = TRUE;  // Make font italic
  601.       lFont.lfHeight = 20;    // 20 pixels high
  602.       lFont.lfWeight = 400;   // Non-bold
  603.       hDlgFont2 = CreateFontIndirect(&lFont);
  604.  
  605.       // Send WM_SETFONT message to desired control
  606.       SendDlgItemMessage(hWndDlg, IDC_TITLE2, WM_SETFONT, hDlgFont2, (DWORD)
  607.                          TRUE);
  608.       SetFocus(GetDlgItem(hWndDlg, IDOK));
  609.       return TRUE;
  610.       break;
  611.  
  612.    case WM_CLOSE:
  613.       /* Closing the Dialog behaves the same as Cancel               */
  614.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  615.       break; /* End of WM_CLOSE                                      */
  616.  
  617.    case WM_PAINT:
  618.       PostMessage(hWndDlg, WM_REPAINT, 0, 0L);
  619.       return FALSE;
  620.  
  621.    case WM_REPAINT:
  622.       DrawIndent(hWndDlg, IDC_BOX1, 1);
  623.       break;
  624.  
  625.    case WM_COMMAND:
  626.       switch (wParam)
  627.          {
  628.       case IDOK:
  629.  
  630.       case IDCANCEL:
  631.          DeleteObject(hDlgFont1);
  632.          DeleteObject(hDlgFont2);
  633.          EndDialog(hWndDlg, TRUE);
  634.          break;
  635.          }
  636.       break;    /* End of WM_COMMAND                                 */
  637.  
  638.    default:
  639.       return FALSE;
  640.       }
  641.    return TRUE;
  642. } /* End of DIALOGSMsgProc                                      */
  643.  
  644.  
  645.  
  646. /************************************************************************
  647.  *
  648.  * StretchIconToWindow()
  649.  *
  650.  * Draws the specified icon on the specified window, filling up the entire
  651.  * window's client area.  The icon must be one of the application's
  652.  * resources.
  653.  *
  654.  ************************************************************************/
  655.  
  656.  
  657. void StretchIconToWindow(HWND hWndDlg,      // window to paint to 
  658.                          LPSTR szIconName)  // name of ICON RESOURCE (not icon file!)
  659. {
  660.    HDC hDC, hMemDC;        // hDC is DC to window, hMemDC is DC to draw icon on
  661.    HICON hIcon;            // Handle to the loaded icon
  662.    RECT rRect;             // RECT of the window's client area coordinates
  663.    HBITMAP hBitmap,        // Handle to bitmap for hMemDC
  664.            hOldBitmap;     // Old Bitmap in hMemDC
  665.    BOOL bReturn;           // To Check return value from StretchBlt
  666.    HBRUSH hOldBrush;       // Handle to old brush in hMemDC
  667.    HBRUSH hBkgdBrush;      // Brush to paint background
  668.  
  669.    hDC = GetDC(hWndDlg);     // Get DC to window
  670.    GetClientRect(hWndDlg, (LPRECT)&rRect); // Get size
  671.  
  672.    // Load the icon
  673.    hIcon = LoadIcon(ghInst, szIconName);
  674.    if (!hIcon)
  675.       return;
  676.  
  677.    // To stretch the icon to the size of the Window specified, we do this:
  678.    // 1. Create a Memory DC (compatible with the window we are drawing to)
  679.    // 2. Create a compatible bitmap and select it into the Memory DC
  680.    // 3. Draw our icon on the Memory DC
  681.    // 4. StretchBlt it into our destination window
  682.    hMemDC = CreateCompatibleDC(hDC);
  683.    hBitmap = CreateCompatibleBitmap(hDC, 64, 64);  // make it big enough to hold icon
  684.  
  685.    // Select the new bitmap into the DC, then paint the background gray.  This
  686.    // is done so that any transparent part of the icon will show through as
  687.    // gray.
  688.    hOldBitmap = SelectObject(hMemDC, hBitmap);
  689.    hBkgdBrush = CreateSolidBrush(RGB(255,255,255));
  690.    hOldBrush = SelectObject(hMemDC, hBkgdBrush);
  691.  
  692.    // Draw rectangle with offset of (-1,-1) for upper left corner - this is
  693.    // to make sure we cover the entire client area of the window
  694.    Rectangle(hMemDC, rRect.left - 1, rRect.top - 1, rRect.right, rRect.bottom)
  695.    ;
  696.  
  697.    //Draw the icon on the memory DC
  698.    DrawIcon(hMemDC, 0, 0, hIcon);
  699.  
  700.    // StretchBlt the icon to fill up the complete destination window.  Note
  701.    // that this is hard-coded for 32x32 icons, which is valid for EGA,VGA and
  702.    // 8514 resolutions for Windows 3.0.
  703.    bReturn = StretchBlt(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom,
  704.                         hMemDC, 0, 0, 32, 32, SRCCOPY);
  705.  
  706.    // Clean up
  707.    SelectObject(hMemDC, hOldBitmap);
  708.    SelectObject(hMemDC, hOldBrush);
  709.    DeleteObject(hBitmap);
  710.    DeleteObject(hBkgdBrush);
  711.    DeleteDC(hMemDC);
  712.  
  713.    // Validate rect of the client our WM_PAINT case dosen't try to paint over it
  714.    ValidateRect(hWndDlg, &rRect);
  715.    ReleaseDC(hWndDlg, hDC);
  716. }
  717.  
  718.  
  719. /************************************************************************
  720.  * cwCenter()
  721.  *
  722.  * Centers a window in the center of the screen.  To do this, we find the
  723.  * dimensions of the screen, the dimensions of the window, and do some
  724.  * calculations to center it on the screen, then call MoveWindow() on the
  725.  * window.
  726.  *
  727.  *
  728.  ************************************************************************/
  729.  
  730.  
  731. void cwCenter(HWND hWnd,        // Handle to the window to be centered
  732.               int top)          // adjust vertical position either up (positive
  733.                                 // values) or down (negative values)
  734. {
  735.    POINT pt;
  736.    RECT rDialog;      // Rect of dialog
  737.    int iDlgWidth;     // width of dialog box
  738.    int iDlgHeight;    // height of dialog box
  739.    HDC hDC;           // hDC to entire screen
  740.  
  741.    /* Figure out how big screen is, then calculate center point of screen */
  742.  
  743.    hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  744.    pt.x = (GetDeviceCaps(hDC, HORZRES) / 2);
  745.    pt.y = (GetDeviceCaps(hDC, VERTRES) / 2);
  746.    DeleteDC(hDC);
  747.  
  748.    /* Get rect of the dialog box, and calculate the height and width  */
  749.    GetWindowRect(hWnd, &rDialog);
  750.    iDlgHeight = rDialog.bottom - rDialog.top;
  751.    iDlgWidth = rDialog.right - rDialog.left;
  752.  
  753.    /* calculate the new x, y starting point                               */
  754.    pt.x = pt.x - iDlgWidth / 2;
  755.    pt.y = pt.y - iDlgHeight / 2;
  756.  
  757.    /* top will adjust the window position, up or down                     */
  758.    if (top)
  759.       pt.y = pt.y + top;
  760.  
  761.    /* move the window                                                     */
  762.    MoveWindow(hWnd, pt.x, pt.y, iDlgWidth, iDlgHeight, FALSE);
  763. }
  764.  
  765. /************************************************************************
  766.  * DrawIndent()
  767.  *
  768.  * Draws a 3-D "Indent", or shadow for the specified control within
  769.  * a dialog box.  This routine also takes a third parameter, which can be set
  770.  * to 1 for a groupbox control, and 2 for a frame control.  Specifying a 2
  771.  * causes this procedure to draw a rectangle around the window also.
  772.  *
  773.  * This code is based on the Microsoft KnowledgeBase article
  774.  * "How to Give a 3_d Effect to Windows Controls"
  775.  *
  776.  ************************************************************************/
  777.  
  778.  
  779. void DrawIndent(HWND hDlg, int ID, int iType)
  780.  
  781. // Assumptions:
  782. //
  783. // hDlg        is a valid window handle.
  784. // ID          is a valid control ID.
  785. // iType       is 1 or 2.  2 will draw a rectangle around the control
  786. {
  787.    RECT rRect;   // RECT which contains control window's coordinates (in client coords)
  788.    HDC hDC;     // HDC to control's window
  789.    HPEN hOldPen; // save old pen so we can select it back in
  790.    HPEN hPenSmall;   // Pen for outlining
  791.    HPEN hPenShadow;  // Pen for shadowing
  792.    HBRUSH hBrushOld; // Save it so we can restore it
  793.  
  794.    // Find out how big the control's window is
  795.  
  796.    GetClientRect(GetDlgItem(hDlg, ID), (LPRECT)&rRect);
  797.    hDC = GetDC(GetDlgItem(hDlg, ID));
  798.  
  799.    // Create the pens which will draw the shadows (and borders)
  800.    hPenSmall = CreatePen(PS_SOLID, 1, RGB(0,0,0));         // Black, 1 pixel wide
  801.    hPenShadow = CreatePen(PS_SOLID, 4, RGB(160,160,160));  // Grayish, 4 pixels wide
  802.    hOldPen = SelectObject(hDC, hPenShadow);
  803.  
  804.    // Draw the Shadow
  805.    MoveTo(hDC, rRect.right + 2, rRect.top + 13);
  806.    LineTo(hDC, rRect.right + 2, rRect.bottom + 2);
  807.    LineTo(hDC, rRect.left + 6, rRect.bottom + 2);
  808.  
  809.    // If iType is 2, draw the border around the window (with small pen) also
  810.    if (iType == 2)
  811.    {
  812.       SelectObject(hDC, hPenSmall);
  813.       hBrushOld = SelectObject(hDC, GetStockObject(NULL_BRUSH));
  814.       Rectangle(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom);
  815.       SelectObject(hDC, hBrushOld);
  816.    }
  817.  
  818.    // Housekeep
  819.    SelectObject(hDC, hOldPen);
  820.    DeleteObject(hPenShadow);
  821.    DeleteObject(hPenSmall);
  822.    ReleaseDC(GetDlgItem(hDlg, ID), hDC);
  823. }
  824.